home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / GLUT / progs / examples / spots.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  9KB  |  348 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /* Copyright (c) Mark J. Kilgard, 1994. */
  5.  
  6. /**
  7.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  8.  * ALL RIGHTS RESERVED 
  9.  * Permission to use, copy, modify, and distribute this software for 
  10.  * any purpose and without fee is hereby granted, provided that the above
  11.  * copyright notice appear in all copies and that both the copyright notice
  12.  * and this permission notice appear in supporting documentation, and that 
  13.  * the name of Silicon Graphics, Inc. not be used in advertising
  14.  * or publicity pertaining to distribution of the software without specific,
  15.  * written prior permission. 
  16.  *
  17.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  18.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  19.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  20.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  21.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  22.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  23.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  24.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  25.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  26.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  27.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  28.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  29.  * 
  30.  * US Government Users Restricted Rights 
  31.  * Use, duplication, or disclosure by the Government is subject to
  32.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  33.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  34.  * clause at DFARS 252.227-7013 and/or in similar or successor
  35.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  36.  * Unpublished-- rights reserved under the copyright laws of the
  37.  * United States.  Contractor/manufacturer is Silicon Graphics,
  38.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  39.  *
  40.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  41.  */
  42.  
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <math.h>
  47. #include <GL/glut.h>
  48.  
  49. #define TWO_PI    (2*M_PI)
  50.  
  51. typedef struct lightRec {
  52.   float amb[4];
  53.   float diff[4];
  54.   float spec[4];
  55.   float pos[4];
  56.   float spotDir[3];
  57.   float spotExp;
  58.   float spotCutoff;
  59.   float atten[3];
  60.  
  61.   float trans[3];
  62.   float rot[3];
  63.   float swing[3];
  64.   float arc[3];
  65.   float arcIncr[3];
  66. } Light;
  67.  
  68. static int useSAME_AMB_SPEC = 1;
  69. /* *INDENT-OFF* */
  70. static float modelAmb[4] = {0.2, 0.2, 0.2, 1.0};
  71.  
  72. static float matAmb[4] = {0.2, 0.2, 0.2, 1.0};
  73. static float matDiff[4] = {0.8, 0.8, 0.8, 1.0};
  74. static float matSpec[4] = {0.4, 0.4, 0.4, 1.0};
  75. static float matEmission[4] = {0.0, 0.0, 0.0, 1.0};
  76. /* *INDENT-ON* */
  77.  
  78. #define NUM_LIGHTS 3
  79. static Light spots[] =
  80. {
  81.   {
  82.     {0.2, 0.0, 0.0, 1.0},  /* ambient */
  83.     {0.8, 0.0, 0.0, 1.0},  /* diffuse */
  84.     {0.4, 0.0, 0.0, 1.0},  /* specular */
  85.     {0.0, 0.0, 0.0, 1.0},  /* position */
  86.     {0.0, -1.0, 0.0},   /* direction */
  87.     {20.0},
  88.     {60.0},             /* exponent, cutoff */
  89.     {1.0, 0.0, 0.0},    /* attenuation */
  90.     {0.0, 1.25, 0.0},   /* translation */
  91.     {0.0, 0.0, 0.0},    /* rotation */
  92.     {20.0, 0.0, 40.0},  /* swing */
  93.     {0.0, 0.0, 0.0},    /* arc */
  94.     {TWO_PI / 70.0, 0.0, TWO_PI / 140.0}  /* arc increment */
  95.   },
  96.   {
  97.     {0.0, 0.2, 0.0, 1.0},  /* ambient */
  98.     {0.0, 0.8, 0.0, 1.0},  /* diffuse */
  99.     {0.0, 0.4, 0.0, 1.0},  /* specular */
  100.     {0.0, 0.0, 0.0, 1.0},  /* position */
  101.     {0.0, -1.0, 0.0},   /* direction */
  102.     {20.0},
  103.     {60.0},             /* exponent, cutoff */
  104.     {1.0, 0.0, 0.0},    /* attenuation */
  105.     {0.0, 1.25, 0.0},   /* translation */
  106.     {0.0, 0.0, 0.0},    /* rotation */
  107.     {20.0, 0.0, 40.0},  /* swing */
  108.     {0.0, 0.0, 0.0},    /* arc */
  109.     {TWO_PI / 120.0, 0.0, TWO_PI / 60.0}  /* arc increment */
  110.   },
  111.   {
  112.     {0.0, 0.0, 0.2, 1.0},  /* ambient */
  113.     {0.0, 0.0, 0.8, 1.0},  /* diffuse */
  114.     {0.0, 0.0, 0.4, 1.0},  /* specular */
  115.     {0.0, 0.0, 0.0, 1.0},  /* position */
  116.     {0.0, -1.0, 0.0},   /* direction */
  117.     {20.0},
  118.     {60.0},             /* exponent, cutoff */
  119.     {1.0, 0.0, 0.0},    /* attenuation */
  120.     {0.0, 1.25, 0.0},   /* translation */
  121.     {0.0, 0.0, 0.0},    /* rotation */
  122.     {20.0, 0.0, 40.0},  /* swing */
  123.     {0.0, 0.0, 0.0},    /* arc */
  124.     {TWO_PI / 50.0, 0.0, TWO_PI / 100.0}  /* arc increment */
  125.   }
  126. };
  127.  
  128. static void
  129. usage(char *name)
  130. {
  131.   printf("\n");
  132.   printf("usage: %s [options]\n", name);
  133.   printf("\n");
  134.   printf("  Options:\n");
  135.   printf("    -geometry Specify size and position WxH+X+Y\n");
  136.   printf("    -lm       Toggle lighting(SPECULAR and AMBIENT are/not same\n");
  137.   printf("\n");
  138. #ifndef EXIT_FAILURE /* should be defined by ANSI C <stdlib.h> */
  139. #define EXIT_FAILURE 1
  140. #endif
  141.   exit(EXIT_FAILURE);
  142. }
  143.  
  144. static void
  145. initLights(void)
  146. {
  147.   int k;
  148.  
  149.   for (k = 0; k < NUM_LIGHTS; ++k) {
  150.     int lt = GL_LIGHT0 + k;
  151.     Light *light = &spots[k];
  152.  
  153.     glEnable(lt);
  154.     glLightfv(lt, GL_AMBIENT, light->amb);
  155.     glLightfv(lt, GL_DIFFUSE, light->diff);
  156.  
  157.     if (useSAME_AMB_SPEC)
  158.       glLightfv(lt, GL_SPECULAR, light->amb);
  159.     else
  160.       glLightfv(lt, GL_SPECULAR, light->spec);
  161.  
  162.     glLightf(lt, GL_SPOT_EXPONENT, light->spotExp);
  163.     glLightf(lt, GL_SPOT_CUTOFF, light->spotCutoff);
  164.     glLightf(lt, GL_CONSTANT_ATTENUATION, light->atten[0]);
  165.     glLightf(lt, GL_LINEAR_ATTENUATION, light->atten[1]);
  166.     glLightf(lt, GL_QUADRATIC_ATTENUATION, light->atten[2]);
  167.   }
  168. }
  169.  
  170. static void
  171. aimLights(void)
  172. {
  173.   int k;
  174.  
  175.   for (k = 0; k < NUM_LIGHTS; ++k) {
  176.     Light *light = &spots[k];
  177.  
  178.     light->rot[0] = light->swing[0] * sin(light->arc[0]);
  179.     light->arc[0] += light->arcIncr[0];
  180.     if (light->arc[0] > TWO_PI)
  181.       light->arc[0] -= TWO_PI;
  182.  
  183.     light->rot[1] = light->swing[1] * sin(light->arc[1]);
  184.     light->arc[1] += light->arcIncr[1];
  185.     if (light->arc[1] > TWO_PI)
  186.       light->arc[1] -= TWO_PI;
  187.  
  188.     light->rot[2] = light->swing[2] * sin(light->arc[2]);
  189.     light->arc[2] += light->arcIncr[2];
  190.     if (light->arc[2] > TWO_PI)
  191.       light->arc[2] -= TWO_PI;
  192.   }
  193. }
  194.  
  195. static void
  196. setLights(void)
  197. {
  198.   int k;
  199.  
  200.   for (k = 0; k < NUM_LIGHTS; ++k) {
  201.     int lt = GL_LIGHT0 + k;
  202.     Light *light = &spots[k];
  203.  
  204.     glPushMatrix();
  205.     glTranslatef(light->trans[0], light->trans[1], light->trans[2]);
  206.     glRotatef(light->rot[0], 1, 0, 0);
  207.     glRotatef(light->rot[1], 0, 1, 0);
  208.     glRotatef(light->rot[2], 0, 0, 1);
  209.     glLightfv(lt, GL_POSITION, light->pos);
  210.     glLightfv(lt, GL_SPOT_DIRECTION, light->spotDir);
  211.     glPopMatrix();
  212.   }
  213. }
  214.  
  215. static void
  216. drawLights(void)
  217. {
  218.   int k;
  219.  
  220.   glDisable(GL_LIGHTING);
  221.   for (k = 0; k < NUM_LIGHTS; ++k) {
  222.     Light *light = &spots[k];
  223.  
  224.     glColor4fv(light->diff);
  225.  
  226.     glPushMatrix();
  227.     glTranslatef(light->trans[0], light->trans[1], light->trans[2]);
  228.     glRotatef(light->rot[0], 1, 0, 0);
  229.     glRotatef(light->rot[1], 0, 1, 0);
  230.     glRotatef(light->rot[2], 0, 0, 1);
  231.     glBegin(GL_LINES);
  232.     glVertex3f(light->pos[0], light->pos[1], light->pos[2]);
  233.     glVertex3f(light->spotDir[0], light->spotDir[1], light->spotDir[2]);
  234.     glEnd();
  235.     glPopMatrix();
  236.   }
  237.   glEnable(GL_LIGHTING);
  238. }
  239.  
  240. static void
  241. drawPlane(int w, int h)
  242. {
  243.   int i, j;
  244.   float dw = 1.0 / w;
  245.   float dh = 1.0 / h;
  246.  
  247.   glNormal3f(0.0, 0.0, 1.0);
  248.   for (j = 0; j < h; ++j) {
  249.     glBegin(GL_TRIANGLE_STRIP);
  250.     for (i = 0; i <= w; ++i) {
  251.       glVertex2f(dw * i, dh * (j + 1));
  252.       glVertex2f(dw * i, dh * j);
  253.     }
  254.     glEnd();
  255.   }
  256. }
  257.  
  258. int spin = 0;
  259.  
  260. void
  261. display(void)
  262. {
  263.   glClear(GL_COLOR_BUFFER_BIT);
  264.  
  265.   glPushMatrix();
  266.   glRotatef(spin, 0, 1, 0);
  267.  
  268.   aimLights();
  269.   setLights();
  270.  
  271.   glPushMatrix();
  272.   glRotatef(-90.0, 1, 0, 0);
  273.   glScalef(1.9, 1.9, 1.0);
  274.   glTranslatef(-0.5, -0.5, 0.0);
  275.   drawPlane(16, 16);
  276.   glPopMatrix();
  277.  
  278.   drawLights();
  279.   glPopMatrix();
  280.  
  281.   glutSwapBuffers();
  282. }
  283.  
  284. void
  285. animate(void)
  286. {
  287.   spin += 0.5;
  288.   if (spin > 360.0)
  289.     spin -= 360.0;
  290.   glutPostRedisplay();
  291. }
  292.  
  293. void
  294. visibility(int state)
  295. {
  296.   if (state == GLUT_VISIBLE) {
  297.     glutIdleFunc(animate);
  298.   } else {
  299.     glutIdleFunc(NULL);
  300.   }
  301. }
  302.  
  303. int
  304. main(int argc, char **argv)
  305. {
  306.   int i;
  307.  
  308.   glutInit(&argc, argv);
  309.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  310.   /* process commmand line args */
  311.   for (i = 1; i < argc; ++i) {
  312.     if (!strcmp("-lm", argv[i])) {
  313.       useSAME_AMB_SPEC = !useSAME_AMB_SPEC;
  314.     } else {
  315.       usage(argv[0]);
  316.     }
  317.   }
  318.  
  319.   glutCreateWindow("GLUT spotlight swing");
  320.   glutDisplayFunc(display);
  321.   glutVisibilityFunc(visibility);
  322.  
  323.   glMatrixMode(GL_PROJECTION);
  324.   glFrustum(-1, 1, -1, 1, 2, 6);
  325.  
  326.   glMatrixMode(GL_MODELVIEW);
  327.   glTranslatef(0.0, 0.0, -3.0);
  328.   glRotatef(45.0, 1, 0, 0);
  329.  
  330.   glEnable(GL_LIGHTING);
  331.   glEnable(GL_NORMALIZE);
  332.  
  333.   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb);
  334.   glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
  335.   glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
  336.  
  337.   glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb);
  338.   glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff);
  339.   glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
  340.   glMaterialfv(GL_FRONT, GL_EMISSION, matEmission);
  341.   glMaterialf(GL_FRONT, GL_SHININESS, 10.0);
  342.  
  343.   initLights();
  344.  
  345.   glutMainLoop();
  346.   return 0;             /* ANSI C requires main to return int. */
  347. }
  348.